; This file contains an adapter for Printer Dumper written in C
; to the RISCOS Printer Dumper system
; Created 06-22-2002 T. Milius
; Changed 10-06-2004 T. Milius
; (c) Copyright 2002-2004 by Thomas Milius Stade, Germany

	AREA	|C$$code|, CODE, READONLY
	IMPORT	|printer_driver_handler|
	EXPORT	|printer_driver_handler_adap|

|printer_driver_handler_adap|
; We are in SVC mode
; there should be enough space on the module stack to save most register except ip and the pc
; Note: ! can't be used for sp is changed on stack already because it is not the first
; register. So the stack pointer must be corrected
	STMFD	sp, {r0-r9, sl, fp, sp, lr}
; Correct Stack pointer
	SUB	sp, sp, #&38
; C-Program can manipulate the registers as memory but needs the location at the stack
	MOV	r0, sp
; the private Word is needed inside the C-program
	MOV	r1, ip
; Set C-Range by loading the base with the content of the C-private word pointer
;	LDR	r9, [ip]
; Module stack does not worry about sl but C does. So sl must set up correctly
	MOV	sl, sp, LSR #20
	MOV	sl, sl, LSL #20
; Save possible old references at Workspace limit in some unused registers
	LDMIA	sl, {r4,r5}
; Copy content from C-Workspace to Workspace limit for reference purposes inside C
	LDR	ip, [ip]
	LDMIB	ip, {fp, ip}
	STMIA	sl, {fp, ip}
; sl is 512 above megabyte boundary of sp and the stack descriptor (size &1c)
	ADD	sl, sl, #&21c
; No backtrace structure
	MOV	fp, #0
; Now call C
;	MOV	ip, pc
	BL	|printer_driver_handler|
; Restore possible old references at Workspace limit
	SUB	sl, sl, #&21c
	STMIA	sl, {r4,r5}
; r0 must be kept in error case
	MOV	ip, r0
; Check whether pointer to error has been passed
	CMP	r0, #0
; If r0 is 0 comparation with 0 will clear the V-flag.
; Else it might be set. However this is not of any interest
; here because the flag will be set explicitly later.
; This is a difference to TEQ which will leave V-flag
; unchanged. On the other side this test shall set the
; Z-flag as required to detect an error or not.
; Jump back to Printer module if all is ok
	LDMEQFD	sp, {r0-r9, sl, fp, sp, pc}
; Restore the registers from stack
	LDMFD	sp, {r0-r9, sl, fp, sp, lr}
; r0 must be replaced with error pointer
	MOV	r0, ip
; load pc with link register now but with error flag set
; 32 or 26 Bit
	TEQ	PC, PC
; 26 Bit
	ORRNES	pc, lr, #&10000000
; 32 Bit
	MRS	ip, CPSR
	ORR	ip, ip, #&10000000
	MSR	CPSR_f, ip
	MOV	pc, lr

	END
